[TOC] ¿Qué quieres decir?
¿Qué puede hacer FMZ Quant Trading Platform?
FMZ Quant Trading es la comunidad cuantitativa más profesional en el campo del comercio cuantitativo. Aquí puedes aprender, escribir, compartir, comprar y vender estrategias cuantitativas; puedes realizar backtesting en línea y usar robots de simulación para realizar operaciones simuladas; también puedes ejecutar, publicar y ver operaciones en vivo.
Serie completa de tutoriales
Tutoriales gráficos:
Si hay algún problema, puede publicar preguntas y discutir en el foro en cualquier momento, o enviar un ticket, o ponerse en contacto con un administrador en el grupo de Telegram (Telegrama), en general, la pregunta será respondida rápidamente.
Apoyo a ChatGPT para la ayuda al desarrollo
FMZ Quantitative Trading Platform ha adoptado ChatGPT como herramienta de asistencia al desarrollo, a la que se puede acceder haciendo clic en
¿Qué lenguajes de programación están disponibles para implementar mis estrategias?
La plataforma de comercio de FMZ Quant es compatible con el usoJavaScript
, TypeScript
, Python
, C++
, Pine
Mylanguage
yBlockly Visualization
para escribir y diseñar estrategias.
ApoyaTypeScript
lenguaje, todavía ponerlo aJavaScript
estrategia cuando creamos estrategias, entonces escribimos// @ts-check
al principio del código de estrategia o haga clic en el botónTypeScript
en la esquina superior derecha del área de edición de la estrategia para cambiar aTypeScript
La plataforma reconocerá el código comoTypeScript
automáticamente y le proporcionará el apoyo adecuado para la compilación y verificación de tipo de:
TypeScript
La función de comprobación de tipo estático de la aplicación puede ayudarle a encontrar posibles errores al escribir código y mejorar la calidad del código.TypeScript
El sistema de tipos de Microsoft hace que sea más rápido encontrar los atributos y métodos que necesita al escribir código, mejorando la eficiencia del desarrollo.TypeScript
, puede organizar y mantener mejor su código, haciéndolo fácil de leer y entender.TypeScript
proporciona poderosas características de programación orientada a objetos, como interfaces, clases, genéricos y así sucesivamente, ayudándote a escribir un código de estrategia más robusto y reutilizable.Solo necesita dominar uno de estos lenguajes. Además de apoyar la forma de diseñar estrategias escribiendo código, también puede crear estrategias utilizando módulos visuales (Blockly). El módulo de visualización de empalme y estrategia de construcción, sin codificación, adopta una forma más intuitiva de diseñar estrategias, lo que es muy adecuado para cultivar interés en el diseño de estrategias para comenzar rápidamente con el comercio programático y cuantitativo.
Blockly
Tutoriales de visualización:
Configurar el
Python
el intérprete utilizado por elPython
Programa de estrategia
Las estrategias escritas enPython
, cuando se realiza backtesting o trading en vivo, si el entorno del sistema docker tiene ambosPython2yPython3instalado, se puede establecer elPython
La versión que se lanzará en tiempo de ejecución en la primera línea de la estrategia, como#!python3
y#!python2
, para que el sistema encuentre el intérprete automáticamente. Y también puede especificar una ruta absoluta, como:#!/usr/bin/python3
.
¿Qué es Docker?
Docker puede entenderse como el ejecutor de su estrategia comercial, responsable de las solicitudes de datos complejos, recepción de datos, enlaces de red, log postback y así sucesivamente.Linux, Las ventanas, Mac OS, Android, Raspberry Pi ARM Linuxy otros sistemas.Página de Docker, Etapas de instalación y actualización del docker de LinuxLos bots y registros administrados por el docker se almacenan en el directorio./logs/storage
El expediente es unSqlite
archivo de base de datos condb3
, que puede ser editado directamente por elSqlite
para un archivo con extensióndb3
En la base de datos de bots reales, el nombre del archivo es el bot ID.
Protocolos soportados
Cuando se desarrollan estrategias de trading en la plataforma FMZ Quant Trading, el contenido de la estrategia solo es visible para los titulares de cuentas de FMZ.Python
El paquete, que se carga en el código de la estrategia, de modo que la localización de contenido de la estrategia se puede realizar.
La seguridad dePython
el código:
¿Por qué?Python
es un lenguaje de código abierto que es extremadamente fácil de descompilar, si la estrategia no es para uso personal sino para alquiler, puede ejecutar la estrategia en su propio docker desplegado y alquilarla en forma de subcuenta o administración completa de docker si le preocupa la fuga de estrategia.
El cifrado dePython
Código de estrategia:
Por defecto,Python
El código de estrategia no está cifrado cuando es utilizado por el autor y está cifrado cuando se alquila a otros.
Mediante la edición del siguiente código al comienzo delPython
En el caso de la estrategia, puede especificar si desea cifrar el código de la estrategia para uso personal o alquiler.Python
Las versiones que admiten el cifrado de los códigos de estrategia son las siguientes:Python 2.7
, Python 3.5
yPython 3.6
.
#!python
como la versión del intérprete de Python, y luego utilizar,
para mantener separado; introduzca el comando de cifradoencrypt
Si no especifica la versión dePython
, añadir#!,encrypt
directly. #!python,encrypt
¿ O qué?
#!encrypt
#!python, not encrypted
¿ O qué?
#!not encrypted
Utilice el códigoos.getenv('__FMZ_ENV__')
para determinar si el código de cifrado es válido; la devolución de la cadena"encrypt"
Indica que ha entrado en vigor. Sólo es válido en el bot real, y el backtest no cifrará elPython
Códigos de estrategia.
#!encrypt
def main():
ret = os.getenv('__FMZ_ENV__')
# If the print variable ret is the string "encrypt" or ret == "encrypt" is true, that means the encryption is valid.
Log(ret, ret == "encrypt")
Los datos confidenciales, como la información de la cuenta y las cadenas cifradas en los parámetros de estrategia configurados en la plataforma de negociación de FMZ Quant, se cifran en el navegador web. Toda la información almacenada en la plataforma de negociación de FMZ Quant está cifrada (no datos de texto plano), y solo los usuarios pueden descifrar y usar la información, lo que mejora enormemente la seguridad de los datos confidenciales.
RSA KEY
método de autenticación del intercambio como un ejemplo para explicar en detalle cómo configurar información confidencial localmente en el dispositivo donde se encuentra el programa docker.PKCS#8
, hay muchas herramientas disponibles para la creación, tales comoopenssl
.RSA KEY
en el intercambio, y subir la clave pública creada enPaso 1durante la creación.txt
archivo, o en otras rutas en el directorio del programa docker.RSA KEY
Creado por el intercambio en el cuadro de edición de la configuraciónAccess Key
.txt
archivo colocado en el mismo directorio de nivel del docker en elPaso 3en el cuadro de edición de la configuraciónSecret Key
Por ejemplo, si el nombre del archivo colocado es:rsaKey.txt
, y el archivo y el docker se llenan en el mismo directorio de nivel:file:///rsaKey.txt
. Si el archivo está en el directorio al lado del directorio del programa dockerrsa_key
, cumplimentar:file:///rsa_key//rsaKey.txt
Si usted colocarsaKey. txt
En cualquier otro lugar de su computadora o servidor siga estas instrucciones en consecuencia, debe tenerse en cuenta que este archivo sólo se puede colocar en directorios de mismo nivel o subdirectorios con respecto a Docker.Esto hace que sea más seguro localizar y guardar la clave privada, se puede referir aVideo de explicaciónpara un proceso detallado.
¿Qué es un sistema de backtest y para qué se utiliza?
Después de haber completado el diseño de una estrategia comercial cuantitativa, ¿cómo puede conocer la situación básica de su estrategia, como la lógica de la estrategia y la dirección de los retornos de la estrategia?
¿Son exactos los datos del sistema de backtest y qué pasa con la exactitud de los resultados de backtest?
La plataforma de comercio de FMZ Quant divide el sistema de backtest ennivel de mercado realynivel de simulaciónEl nivel real del mercado es para backtest completamente de acuerdo con los datos históricos completos; mientras que el nivel de simulación backtest generatick
Los datos se basan en datos históricos reales, pero los datos reales de mercado son más precisos y los resultados más creíbles.Descripción del mecanismo de prueba de retroceso FMZSin embargo, el backtesting es solo el rendimiento de la estrategia según los datos históricos. Los datos históricos no pueden representar completamente el mercado futuro. El mercado histórico puede repetirse, o también puede conducir al Cisne Negro. Por lo tanto, los resultados del backtest deben tratarse de manera racional y objetiva.
Cuestiones a tener en cuenta al hacer pruebas de retroceso de diferentes estrategias de lenguaje de programación:
El backtest deJavaScript tambiényC++estrategias de negociación se lleva a cabo en el navegador, y el bot de mercado real oWexApp es una aplicaciónEn la actualidad, el mercado real de divisas emulado (es decir, elWexApp es una aplicaciónEmulado de intercambio de FMZ Quant Trading plataforma) se ejecuta sin instalar ningún otro software, bibliotecas o módulos. La prueba de retroceso dePythonLa operación de mercado real y la backtest se basan en el funcionamiento de la plataforma de comercio de FMZ.PythonSi se necesitan algunas bibliotecas, deben instalarse manualmente (sólo se admiten bibliotecas comunes en servidores públicos).
Datos de pruebas de retroceso en el sistema
Hay dos tipos de pruebas de retroceso de la plataforma de comercio de FMZ Quant: pruebas de retroceso de nivel de simulación y pruebas de retroceso de nivel de mercado real.tick
Cada período de línea K generará 12 puntos de tiempo de backtesting; sin embargo, el nivel real del mercado recogeticks
El mecanismo de backtest de FMZ permite que la estrategia de trading se negocie varias veces en una sola línea K, evitando la situación en la que la negociación solo se puede ejecutar al precio de cierre. Es más precisa teniendo en cuenta la velocidad de backtest.el Enlace.
Método de estrategia DEBUG en el sistema de backtesting
Prueba de estrategia de backtesting de JavaScript en Chrome DevTools
Valor de la moneda encriptada (Criptomoneda)
Nombre | Tipo de producto | Instrucciones |
---|---|---|
Bitfinex | objeto de intercambio al contado | apoyar pares de operaciones limitados, tales como:BTC_USD , ETH_USD yLTC_USD , etc. (observe que la moneda de cotización de los pares de operaciones esUSD el dólar) |
Binance | objeto de intercambio al contado | apoyar pares de operaciones limitados, tales como:BTC_USDT , ETH_USDT , ETH_BTC yLTC_BTC , etc. |
No hay problema. | objeto de intercambio al contado | apoyar pares de operaciones limitados, tales como:BTC_USDT , ETH_USDT , ETH_BTC yLTC_BTC , etc. |
- ¿ Qué? | objeto de intercambio al contado | apoyar pares de operaciones limitados, tales como:BTC_USDT , ETH_USDT , ETH_BTC yLTC_BTC , etc. |
Futuros de OKX | Objeto de cambio de futuros | apoyar pares de operaciones limitados, tales como:BTC_USD yETH_USD , etc.; la moneda de cotización de los pares de negociación esUSD ; después de la fijación del código de contrato específico (consulte la funciónexchange.SetContractType ), el contrato es un contrato de criptomonedas con margen; los códigos de contrato admitidos incluyen:this_week , next_week , quarter yswap |
- ¿ Qué es eso? | Objeto de cambio de futuros | HuobiDM es Huobi Futures (Contrato Huobi), que admite pares de operaciones limitados, como:BTC_USD yETH_USD , etc.; la moneda de cotización de los pares de operaciones esUSD ; después de la fijación del código de contrato específico (consulte la funciónexchange.SetContractType ), el contrato es un contrato de criptomonedas con margen; los códigos de contrato admitidos incluyen:this_week , next_week , quarter yswap . |
BitMEX | Objeto de cambio de futuros | el par de operaciones esXBT_USD ; después de la fijación del código de contrato específico (consulte la funciónexchange.SetContractType ), el contrato es un contrato de criptomonedas con margen; el código de contrato soportado es:XBTUSD |
Futures de Binance | Objeto de cambio de futuros | apoyar pares de operaciones limitados, tales como:BTC_USDT yETH_USDT , etc.; la moneda de cotización de los pares de negociación esUSD ; después de la fijación del código de contrato específico (consulte la funciónexchange.SetContractType ), el contrato es unUSDT - contrato con margen; el código del contrato apoyado esswap |
Opciones derivadas | Objeto de cambio de futuros | los pares de negociación son:BTC_USD yETH_USD ; después de la fijación del código de contrato específico (consulte la funciónexchange.SetContractType ), el contrato es un contrato de criptomonedas con margen; deben establecerse códigos específicos de contratos de opciones |
Para los objetos de intercambio de futuros en el sistema de backtest, el cambio de pares de negociación no está soportado temporalmente en los códigos de estrategia.
La prueba de retroceso de nivel de simulación se basa en los datos subyacentes de la línea K del sistema de prueba de retroceso, simulando los datos de tick en el marco de los valores del precio más alto, precio más bajo, precio de apertura y precio de cierre de una barra de línea K subyacente dada de acuerdo con un determinado algoritmo.tick
datos cuando se solicita la interfaz.Descripción del mecanismo de prueba posterior de nivel de simulación cuántica FMZ.
La prueba de retroceso a nivel de mercado real es latick
En el caso de las estrategias basadastick
En el caso de los datos de nivel de mercado real, el uso del nivel de mercado real para backtest está más cerca de la realidad.tick
Los datos son datos registrados reales, no simulados. Soporta datos de profundidad, reproducción de datos de registro de las operaciones de mercado, profundidad personalizada y cada dato comercial individual. El tamaño máximo de la prueba de retroceso de datos a nivel de mercado real es de hasta un máximo de 50MB, sin límite en el rango de tiempo de prueba posterior dentro del límite superior del conjunto de datos. Si necesita ampliar el rango de tiempo de prueba posterior tanto como sea posible, puede reducir el valor del equipo de configuración de profundidad de llamada y no utilizar cada dato comercial individual para aumentar el rango de tiempo de prueba posterior.GetDepth
,GetTrades
En un momento de los datos del mercado en la línea de tiempo, llamandoGetTicker
,GetTrades
, GetDepth
yGetRecords
no empujará el tiempo varias veces cuando el tiempo se mueve en la línea de tiempo de backtest (lo que no desencadenará un salto al siguiente momento de datos del mercado). Las llamadas repetidas a una de las funciones anteriores empujarán el tiempo de backtest para moverse en la línea de tiempo de backtest (saltar al siguiente momento de datos del mercado). Cuando se utiliza el nivel real del mercado para backtest, no se recomienda elegir un tiempo anterior. Puede que no haya datos de nivel real del mercado en el período de tiempo prematuro.
El backtest de nivel de mercado real apoya actualmente:
La función de optimización de parámetros del sistema de backtest de la plataforma FMZ Quant Trading es establecer optimizaciones de acuerdo con cada opción de optimización de parámetros durante la backtest, y las opciones se muestran de la siguiente manera:
Generar combinaciones de parámetros, y recorrer todas esas combinaciones para backtest (es decir, backtesting cada combinación de parámetros una vez).NúmeroEl sistema de backtesting puede optimizar el tipo de prueba.
Por ejemplo, establecer opciones de optimización de parámetros en la página de backtest:
La prueba posterior del modo de optimización de parámetros:
En la página de edición de estrategias, en la paginación de
TomarJavaScript
estrategia como ejemplo, y haga clic en
Hay ligeras diferencias en JavaScript
, Python
, cpp
yMylanguage
:
/*backtest
start: 2021-06-26 00:00:00
end: 2021-09-23 00:00:00
period: 1d
basePeriod: 1h
platforms: [{"eid":"Binance","currency":"BTC_USDT"}]
*/
'''backtest
start: 2021-06-26 00:00:00
end: 2021-09-23 00:00:00
period: 1d
basePeriod: 1h
platforms: [{"eid":"Binance","currency":"BTC_USDT"}]
'''
/*backtest
start: 2021-06-26 00:00:00
end: 2021-09-23 00:00:00
period: 1d
basePeriod: 1h
platforms: [{"eid":"Binance","currency":"BTC_USDT"}]
*/
Mi lenguaje:
(*backtest
start: 2021-06-26 00:00:00
end: 2021-09-23 00:00:00
period: 1d
basePeriod: 1h
platforms: [{"eid":"Futures_OKCoin","currency":"BTC_USD"}]
*)
El sistema utiliza elGET
método para solicitar una URL personalizada (URL accesible públicamente) para obtener una fuente de datos externa para backtest.
Parámetro | Significado | Explicación |
---|---|---|
El símbolo | Nombre del símbolo | el valor de las acciones de la entidad |
El día de Eid | Los intercambios | como OKCoin_EN |
En redondo | Precisión de los precios | como 3, el precio en los datos devueltos debe multiplicarse por 1000 y redondearse |
Alrededor | Precisión de las cantidades | como 2, la cantidad en los datos devueltos debe multiplicarse por 100 y redondearse |
Periodo de tiempo | Período de barras (millisegundos) | como 60,000 indicando la barra que solicita un minuto |
Profundidad | Niveles de profundidad | 1-20 |
Negocios | Si es necesario dividir datos | verdadero/falso |
Desde | Tiempo de inicio | el tiempo de unix |
¿Por qué? | El tiempo del fin | el tiempo de unix |
Nota:
Round and V-Round are two parameters designed to avoid losing the precision of floating-point numbers during network transmission. The price data, trading volume and order amount, are all transmitted using integers.
Un ejemplo de los datos cosidos:
http://customserver:80/data?symbol=BTC_USD_OKCoin_EN&eid=OKCoin_EN&round=3&vround=3&period=900000&from=1564315200&to=1567267200
El formato devuelto debe ser uno de los dos formatos siguientes (que el sistema reconocerá automáticamente):
Prueba de retroceso ordinaria a nivel de barra
{
"schema":["time","open","high","low","close","vol"],
"data":[[1564315200000,9531300,9531300,9497060,9497060,787],[1564316100000,9495160,9495160,9474260,9489460,338]]
}
Datos de backtest de nivel de tick (incluida la información sobre la profundidad del mercado, una matriz con un formato de profundidad de [precio, volumen]; puede haber múltiples niveles de profundidad;
asks se refiere a la orden ascendente del precio y bids se refiere a la orden inversa del precio).
{
"schema":["time","asks", "bids","trades","close","vol"],
"data":[[1564315200000,[[9531300,10]], [[9531300,10]],[[1564315200000,0,9531300,10]],9497060,787]]
}
Descripción
El campo | Descripción |
---|---|
Esquema | Especifica los atributos de las columnas de la matriz de datos, que es sensible a mayúsculas y minúsculas y está limitado a |
Datos obtenidos | Una matriz que almacena datos por esquema |
Formato de datos
El campo | Descripción |
---|---|
solicitudes/ofertas | [precio, volumen],...] |
las operaciones | [tiempo, dirección, precio, volumen,...] |
Proporcionar datos sobre las tasas de financiación:
Por ejemplo, cuando se realiza la prueba de retroceso de Binance Futures, es necesario tener datos adicionales de la tasa de financiación, que deben proporcionarse por una fuente de datos personalizada.
{
"detail": {},
"symbol": "futures_binance.eth_usdt.funding",
"schema": ["time", "open", "high", "low", "close", "vol"],
"data": [
[1582876800000, 25289, 25289, 25289, 25289, 0],
[1582905600000, 30522, 30522, 30522, 30522, 0],
[1582934400000, 40998, 40998, 40998, 40998, 0],
...
[1626652800000, 198, 198, 198, 198, 0],
[1626681600000, 691, 691, 691, 691, 0], // The adjacent periodic interval is 8 hours
[1626710400000, 310, 310, 310, 310, 0], // The funding rate of Binance updates every 8 hours, and why the data of the funding rate turns out to be 310?
[1626739200000, 310, 310, 310, 310, 0], // Like the bars data, to avoid losing the precision of floating-point numbers during network transmission, the data uses integer, so the data needs to be processed according to round parameter; the data, returned to the backtest system after processing, is 310
[1626768000000, -41610, -41610, -41610, -41610, 0], // The funding rate might be a negative value
[1626796800000, -5125, -5125, -5125, -5125, 0],
...
[1627977600000, 10000, 10000, 10000, 10000, 0]
]
}
Un ejemplo de la solicitud de datos del sistema de backtest:
http://customserver:80/data?symbol=futures_binance.eth_usdt.funding&eid=Futures_Binance&round=8&vround=5&depth=20&trades=1&custom=0&period=3600000&from=1360771200&to=1628006400
Ejemplo de fuente de datos personalizada:
Especifique la fuente de datos, URL:http://xxx.xx.x.xx:9090/data
Personalizar el servidor de datos, escrito en golang:
package main
import (
"fmt"
"net/http"
"encoding/json"
)
func Handle (w http.ResponseWriter, r *http.Request) {
// e.g. set on backtest DataSourse: http://xxx.xx.x.xx:9090/data
// r.URL: /data?depth=20&detail=true&eid=Binance&from=1566820800&period=900000&round=3&symbol=BTC_USDT_Binance&to=1569686400&trades=1&vround=5
// response
defer func() {
// response data
/* e.g. data
{
"schema":["time","open","high","low","close","vol"],
"data":[
[1564315200000,9531300,9531300,9497060,9497060,787],
[1564316100000,9495160,9495160,9474260,9489460,338]
]
}
*/
ret := map[string]interface{}{
"schema" : []string{"time","open","high","low","close","vol"},
"data" : []interface{}{
[]int64{1564315200000,9531300,9531300,9497060,9497060,787},
[]int64{1564316100000,9495160,9495160,9474260,9489460,338},
},
}
b, _ := json.Marshal(ret)
w.Write(b)
}()
}
func main () {
fmt.Println("listen http://localhost:9090")
http.HandleFunc("/data", Handle)
http.ListenAndServe(":9090", nil)
}
Estrategia de ensayoJavaScript
Ejemplo:
/*backtest
start: 2019-07-28 00:00:00
end: 2019-07-29 00:00:00
period: 1m
platforms: [{"eid":"OKX","currency":"BTC_USDT","feeder":"http://120.24.2.20:9090/data"}]
*/
function main() {
var ticker = exchange.GetTicker()
var records = exchange.GetRecords()
Log(ticker)
Log(records)
}
Gráficos dibujados por los datos personalizados en el sistema de backtest:
Estrategia Imprimir información:
La plataforma de comercio de FMZ Quant ha sido de código abierto para elJavaScript
La versión y elPython
versión del motor local de pruebas de retroceso, configuración compatiblePeríodo de la línea K subyacentedurante el backtesting.
tecla de acceso directo para cambiar entre la página de estrategia
Usa la llave.Ctrl +,
para volver a la página Ctrl
Presiona la tecla.,
.
Clave de acceso directo para la estrategia de ahorro
Usa la llave.Ctrl + s
para salvar estrategias.
Acceso directo para iniciar la estrategia backtest
Usa la llave.Ctrl + b
para permitir
Nombre de la función | Descripción |
---|---|
main() |
Es una función de entrada. |
onexit() |
Es una función de limpieza cuando se sale normalmente, su tiempo máximo de ejecución es de 5 minutos, que puede dejarse sin declarar; si se produce el tiempo de espera, uninterrumpirse informará del error. |
onerror() |
Es una función de salida anormal, su tiempo máximo de ejecución es de 5 minutos, que puede dejarse sin declarar.Python ycpp no soporta esta función. |
init() |
Es una función de inicialización, su programa de estrategia se llamará automáticamente cuando comience a ejecutarse, que puede dejarse sin declarar. |
onerror()
.onerror()
se activa en el bot, la funciónonexit()
No se activará.onexit()
, procesando trabajos de limpieza, con un tiempo máximo de ejecución de 5 minutos, que es realizado por el usuario.
function main(){
Log("Start running, stop after 5 seconds, and execute onexit function!")
Sleep(1000 * 5)
}
// onexit function implementation
function onexit(){
var beginTime = new Date().getTime()
while(true){
var nowTime = new Date().getTime()
Log("The program stops counting down..The cleaning starts and has passed:", (nowTime - beginTime) / 1000, "Seconds!")
Sleep(1000)
}
}
import time
def main():
Log("Start running, stop after 5 seconds, and execute onexit function!")
Sleep(1000 * 5)
def onexit():
beginTime = time.time() * 1000
while True:
ts = time.time() * 1000
Log("The program stops counting down..The cleaning starts and has passed:", (ts - beginTime) / 1000, "Seconds!")
Sleep(1000)
void main() {
Log("Start running, stop after 5 seconds, and execute onexit function!");
Sleep(1000 * 5);
}
void onexit() {
auto beginTime = Unix() * 1000;
while(true) {
auto ts = Unix() * 1000;
Log("The program stops counting down..The cleaning starts and has passed:", (ts - beginTime) / 1000, "Seconds!");
Sleep(1000);
}
}
El usuario implementa la función de inicializacióninit()
, que ejecutará automáticamente la funcióninit()
al comienzo de la estrategia para completar la tarea de inicialización.
function main(){
Log("The first line of the code executed in the program!", "#FF0000")
Log("Exit!")
}
// Initialization Function
function init(){
Log("Initialization!")
}
def main():
Log("The first line of the code is executed!", "#FF0000")
Log("Exit!")
def init():
Log("Initialization!")
void main() {
Log("The first line of the code is executed!", "#FF0000");
Log("Exit!");
}
void init() {
Log("Initialization!");
}
La ejecución de la funciónonerror()
Esta función no admite las estrategias escritas enPython
ycpp
.
function main() {
var arr = []
Log(arr[6].Close)
}
function onerror() {
Log("error")
}
# not supported by python
// not supported by C++
En las estrategias escritas enJavaScript
, Python
ycpp
, elSleep()
En el bot, se utiliza para controlar los intervalos de votación de estrategias, y también controlar la frecuencia de solicitud de acceso a la interfaz API del intercambio.
Ejemplos básicos de estrategias de marco de criptomonedas:
function onTick(){
//Write strategy logic here, and it will be called constantly, such as printing market information
Log(exchange.GetTicker())
}
function main(){
while(true){
onTick()
//The function "Sleep" is mainly used to control the polling frequency of cryptocurrency strategies to prevent accessing the exchange API interafce too frequently
Sleep(60000)
}
}
def onTick():
Log(exchange.GetTicker())
def main():
while True:
onTick()
Sleep(60000)
void onTick() {
Log(exchange.GetTicker());
}
void main() {
while(true) {
onTick();
Sleep(60000);
}
}
Tomemos el ejemplo más simple, si quiero colocar una orden de compra con un precio de 100 y una cantidad de 1 en el intercambio cada segundo, puedo escribirlo así:
function onTick(){
// It is just an example; for all the assets will be used to place orders fast during backtest or in the bot, do not implement the example in the bot
exchange. Buy(100, 1)
}
function main(){
while(true){
onTick()
// The pause period can be customized in millisecond (1 second = 1000 milliseconds)
Sleep(1000)
}
}
def onTick():
exchange.Buy(100, 1)
def main():
while True:
onTick()
Sleep(1000)
void onTick() {
exchange.Buy(100, 1);
}
void main() {
while(true) {
onTick();
Sleep(1000);
}
}
Elbiblioteca de plantillases un módulo de código reutilizable en la plataforma de negociación FMZ Quant, que funciona como una categoría de códigos de estrategia de negociación.Biblioteca de plantillas, una plantilla se agrega en la página
JavaScript
:
Python
:
cpp
:
Función de exportación de
/*
-- This method is called directly with $.Test() after the strategy refers to the template
-- The "main" function will not be triggered in the strategy, and it is only used as the entry point for template debugging
*/
$.Test = function() {
Log('Test')
}
function main() {
$.Test()
}
def Test():
Log("template call")
# Export "Test" function; the main strategy can be called by ext.Test()
ext.Test = Test
// The strategy refers to the template and calls this method directly with ext::Test()
void Test() {
Log("template call");
}
Configuración de parámetros de la biblioteca de plantillas:
Códigos de la biblioteca de plantillas:
$.SetParam1 = function(p1) {
param1 = p1
}
$.GetParam1 = function() {
Log("param1:", param1)
return param1
}
def SetParam1(p1):
global param1
param1 = p1
def GetParam1():
Log("param1:", param1)
return param1
ext.SetParam1 = SetParam1
ext.GetParam1 = GetParam1
void SetParam1(float p1) {
param1 = p1;
}
float GetParam1() {
Log("param1:", param1);
return param1;
}
Consulte el código de estrategia en elBiblioteca de plantillasejemplo mencionado anteriormente:
function main () {
Log("call $.GetParam1:", $.GetParam1())
Log("call $.SetParam1:", "#FF0000")
$.SetParam1(20)
Log("call $.GetParam1:", $.GetParam1())
}
def main():
Log("call ext.GetParam1:", ext.GetParam1())
Log("call ext.SetParam1:", "#FF0000")
ext.SetParam1(20)
Log("call ext.GetParam1:", ext.GetParam1())
void main() {
Log("call ext::GetParam1:", ext::GetParam1());
Log("call ext::SetParam1:", "#FF0000");
ext::SetParam1(20);
Log("call ext::GetParam1:", ext::GetParam1());
}
Cita
Después de comprobar la referencia en la columna de plantilla de la página de edición de la estrategia, guarde la estrategia.
Exchange
El objeto de intercambio se considera como el primer objeto de intercambio añadido en los parámetros de la estrategia.
Añadir objetos de intercambio en
Añadir objetos de intercambio en la página
Los objetos de intercambio añadidos corresponden a laexchange
objetos en el código:
function main() {
Log("The name of the first exchange object added on the bot page or backtest page:", exchange.GetName(), ", Label:", exchange.GetLabel())
}
def main():
Log("The name of the first exchange object added on the bot page or backtest page:", exchange.GetName(), ", Label:", exchange.GetLabel())
void main() {
Log("The name of the first exchange object added on the bot page or backtest page:", exchange.GetName(), ", Label:", exchange.GetLabel());
}
Se puede entender como una matriz que almacena todos los objetos de intercambio comoexchange
objetos de intercambio, que pueden contener múltiples objetos de intercambio;exchanges[0]
esexchange
.
Los objetos de intercambio añadidos corresponden aexchanges[0]
, exchanges[1]
, exchanges[2]
... y así sucesivamente en el código de estrategia.
function main() {
for(var i = 0; i < exchanges.length; i++) {
Log("Index of the exchange object added (the first one is 0 and so on):", i, "Name:", exchanges[i].GetName(), "Label:", exchanges[i].GetLabel())
}
}
def main():
for i in range(len(exchanges)):
Log("Index of the exchange object added (the first one is 0 and so on):", i, "Name:", exchanges[i].GetName(), "Label:", exchanges[i].GetLabel())
void main() {
for(int i = 0; i < exchanges.size(); i++) {
Log("Index of the exchange object added (the first one is 0 and so on):", i, "Name:", exchanges[i].GetName(), "Label:", exchanges[i].GetLabel());
}
}
El atributoStatus
En elOrder
structure.
Nombre constante | Definición | Valor |
---|---|---|
El estado de la orden está pendiente | no terminado | 0 |
Se ha cerrado el proceso de entrega. | terminado | 1 |
El estado de la orden está cancelado. | cancelado | 2 |
El estado de la orden es desconocido. | estado desconocido (otros estados) | 3 |
El estado de la orden es desconocido.El estado puede llamarexchange.GetRawJSON()
para obtener la información de estado del pedido original, consultar el archivo de intercambio y ver la descripción específica.
Los nombres constantes del formulario pueden utilizarse directamente en el código de estrategia para comparar con el atributoStatus
En elOrder
La impresión de los nombres de las constantes mostrará el estado de los ordenes.nombres constantesy sus correspondientesvalores, y otros nombres constantes abajo funcionan de la misma manera, por lo que no habrá descripciones más detalladas sobre ellos.
El atributoType
En elOrder
structure.
Nombre constante | Definición | Valor |
---|---|---|
El valor de las operaciones de compra y venta | Orden de compra | 0 |
El valor de las operaciones de transferencia | Orden de venta | 1 |
El atributoType
En elPosition
structure.
Nombre constante | Definición | Descripción | Aplicable | Valor |
---|---|---|---|---|
Se trata de un sistema de gestión de datos. | Posición larga | Uso de futuros de criptomonedasexchange.SetDirection("closebuy") para establecer la dirección de la posición de cierre, y cerrar este tipo de posiciones |
Futuros de criptomonedas | 0 |
PD_SHORT | Posición corta | Uso de futuros de criptomonedasexchange.SetDirection("closesell") para establecer la dirección de la posición de cierre, y cerrar este tipo de posiciones |
Futuros de criptomonedas | 1 |
El atributoOffset
En elOrder
structure.
Nombre constante | Definición | Valor |
---|---|---|
Se puede utilizar el código de código de la aplicación. | Ordenes de posiciones abiertas | 0 |
Se puede utilizar el código de código de la aplicación. | Ordenes de cierre de posiciones | 1 |
En los códigos de estrategia de negociación, los parámetros de estrategia establecidos en la interfaz de estrategia se reflejan en forma de variables globales.JavaScript
En la interfaz de estrategia, el lenguaje puede acceder directamente a los valores de parámetros establecidos o modificados.Python
estrategias, la palabra claveglobal
El objetivo de la estrategia es modificar las variables globales de la misma.
Tipo de parámetro:
Variable | Descripción | Las observaciones | Tipo de producto | Valor por defecto | Descripción |
---|---|---|---|---|---|
Número | Tipo numérico | Las observaciones | Número (número) | 1 | La estrategia en C++ es un tipo de coma flotante |
Cuadrícula | la cuerda | Las observaciones | Cuadrícula (cuadrícula) | Hola FMZ | El valor predeterminado no necesita ser citado. La entrada se trata como una cadena |
Envases | ComboBox | Las observaciones | ComboBox (seleccionado) | 1|2|3 | La variable combobox en sí es un valor numérico, que representa el índice de la columna seleccionada por el control Combobox. El valor del primer ComboBox es 1, y los demás es 0, y así sucesivamente |
- ¿ Qué? | Opciones de verificación | Las observaciones | Boolean (verdadero/falso) | Es cierto | Si se comprueba, la variable bool es verdadera; si no se comprueba, la variable bool es falsa |
SecretoString | Cuadrícula cifrada | Las observaciones | Cuadrícula cifrada (cuadrícula) | Contraseña | Con el mismo uso que una cadena, la cadena cifrada se enviará por cifrado y no se transmitirá en texto plano |
number
, string
, combox
, bool
, secretString
.Configuración de dependencia de parámetros:
Un parámetro puede ser establecido para permitir que otro parámetro se muestre y oculte en función de la selección del parámetro.numberA
, que es un tipo numérico.numberA
se muestran o ocultan basado en si el parámetroisShowA
(tipo booleano) es verdadero o falso.numberA
en los parámetros de interfaz como:numberA@isShowA
.
De esta manera, si el parámetroisShowA
no se comprueba, el parámetronumberA
En cuanto a los parámetros del tipo de control ComboBox, la parte dependiente de los parámetros es juzgar si el valor del parámetro es igual al valor de lavalor del índiceDe la misma manera, tomar parámetroisShowA
Cuando se establecen las variables en los parámetros, escribir:numberA@combox==2
. El parámetronumberA
mostrará o ocultará, según si el parámetrocombox
se comprobará que es la tercera opción (donde el índice 0 corresponde a la primera opción, el índice 1 corresponde a la segunda y el índice 2 corresponde a la tercera).
Parámetros de interfaz de estrategia, controles interactivos y función de agrupación de parámetros en (?First group)
al comienzo de la descripción del parámetro que inicia la agrupación, tal como se muestra en la figura siguiente:
Cuando se utiliza la estrategia, los parámetros se muestran en grupos:
Guardar el valor predeterminado del parámetro:
Los parámetros de la estrategia se muestran en la figura. Durante la prueba de retroceso, si desea guardar los valores predeterminados de los parámetros de la estrategia, puede hacer clic en elSave settings
botón después de modificar los parámetros de la estrategia.
Puede guardar la configuración de parámetros de estrategia en forma de código:
/*backtest
start: 2020-02-29 00:00:00
end: 2020-03-29 00:00:00
period: 1d
args: [["number",2],["string","Hello FMZ.COM"],["combox",2],["bool",false],["numberA@isShowA",666],["isShowA",true]]
*/
'''backtest
start: 2020-02-29 00:00:00
end: 2020-03-29 00:00:00
period: 1d
args: [["number",2],["string","Hello FMZ.COM"],["combox",2],["bool",false],["numberA@isShowA",666],["isShowA",true]]
'''
/*backtest
start: 2020-02-29 00:00:00
end: 2020-03-29 00:00:00
period: 1d
args: [["number",2],["string","Hello FMZ.COM"],["combox",2],["bool",false],["numberA@isShowA",666],["isShowA",true]]
*/
Algunas funciones estarán acompañadas del originalJSON
datos solicitados durante la llamada.JSON
Los datos se almacenan en el atributoInfo
Dado que el backtest no es para acceder a una interfaz de plataforma, los datos devueltos durante el backtest no tienen ningún atributoInfo
La siguiente es una descripción de los principales atributos de cada estructura de datos.
Obtener todo el historial de operaciones (no el mismo), devuelto por la funciónexchange.GetTrades()
.
{
Id : 9585306, // Trading record ID; if the exchange interface does not provide order ID, use the timestamp to fill in
Time : 1567736576000, // Time (Unix timestamp milliseconds)
Price : 1000, // Price
Amount : 1, // Volume
Type : 0 // Order Type; refer to the order type in the constants; 0 is ORDER_TYPE_BUY, meaning the value of ORDER_TYPE_BUY is 0
}
Las cotizaciones de mercado son devueltas por la funciónexchange.GetTicker()
.
{
Info : {...}, // After requesting the platform interface, this attribute is not available in the raw data that the exchange interface responds to, during the backtest
High : 1000, // Highest price; if the platform interface does not provide the 24-hour highest price, use sell price 1 to fill in
Low : 500, // Lowest price; if the platform interface does not provide the 24-hour lowest price, use buy price 1 to fill in
Sell : 900, // Sell price 1
Buy : 899, // Buy price 1
Last : 900, // Last executed price
Volume : 10000000, // Recent trading volume; in principle, the unit of spot trading volume is base currency, and the unit of futures trading volume is contract quantity. If the platform interface does not provide this kind of data, use the existing data of the platform interface to fill in; for instance, it might be a trading volume in the unit of quote currency
Time : 1567736576000 // Millisecond-level timestamp
}
La normaOHLC
La estructura se utiliza para dibujar K-líneas y el cálculo y análisis de indicadores de proceso.exchange.GetRecords()
devuelve la matriz de estructuras.Record
la estructura representa una barra de k líneas, es decir, una línea kBAR
El.Time
En elRecord
es la hora de inicio del período de barras de la línea K.
{
Time : 1567736576000, // A timestamp, accurate to millisecond, in the same format as the result obtained by Javascript's newDate().GetTime()
Open : 1000, // Open price
High : 1500, // Highest price
Low : 900, // Lowest price
Close : 1200, // Close price
Volume : 1000000 // Trading volume; in principle, the unit of spot trading volume is base currency, and the unit of futures trading volume is contract quantity. If the platform interface does not provide this kind of data, use the existing data of the platform interface to fill in; for instance, it might be a trading volume in the unit of quote currency
}
La estructura de orden puede ser devuelta por funciones, incluyendoexchange.GetOrder()
yexchange.GetOrders()
. La funciónexchange.GetOrders()
devuelve la matriz o una matriz vacía de la estructura (si no hayorden pendiente sin terminar, regresar[]
, es decir, una matriz vacía).
{
Info : {...}, // After requesting the platform interface, this attribute is not available in the raw data that the exchange interface responds to, during the backtest
Id : 123456, // Unique ide